package com.wang.tool.valve.strategy;


import com.wang.tool.util.CommonUtil;

import java.util.List;

/**
 * @Description 常用模型
 * @Author shaopeng
 * @Date 2021/7/21
 * @Version 1.0
 */
public class SimpleValve extends AbsValve {
    private static final long serialVersionUID = -5029358097372575758L;

    /**
     * 白名单
     * 白名单命中返回true
     */
    private List<String> whites;

    /**
     * 黑名单
     * 黑名单命中返回false
     */
    private List<String> blacks;

    /**
     * 比例
     * 0-100
     */
    private Integer rate;

    @Override
    public void prepare() {
        if (whites != null) {
            whites.remove(null);
        }

        if (blacks != null) {
            blacks.remove(null);
        }

        //当rate没设置时做特殊处理
        if (rate == null) {
            if (CommonUtil.isNotEmpty(whites)) {
                //指定了白名单,则是仅白名单通过
                //{
                // whites:["1"]
                // }
                rate = 0;
            } else {
                rate = 100;
            }
        }
    }


    @Override
    protected boolean internalIsPass(Object param) {
        // 非黑名单 && (白名单 || 比例)

        String paramStr = param == null ? null : param.toString();
        //黑名单命中
        if (CommonUtil.isNotEmpty(blacks) && blacks.contains(paramStr)) {
            return false;
        }
        //经过prepare后rate为非空
        //全开
        if (rate >= 100) {
            return true;
        }

        //白名单命中
        if (CommonUtil.isNotEmpty(whites) && whites.contains(paramStr)) {
            return true;
        }

        //没开
        if (rate <= 0 || param == null) {
            return false;
        }

        //数字取尾部
        if (CommonUtil.isNumeric(paramStr)) {
            return Long.parseLong(paramStr) % 100 < rate;
        }
        //hashcode
        return param.hashCode() % 100 < rate;
    }

    public List<String> getWhites() {
        return whites;
    }

    public void setWhites(List<String> whites) {
        this.whites = whites;
    }

    public List<String> getBlacks() {
        return blacks;
    }

    public void setBlacks(List<String> blacks) {
        this.blacks = blacks;
    }

    public Integer getRate() {
        return rate;
    }

    public void setRate(Integer rate) {
        this.rate = rate;
    }

    @Override
    public String toString() {
        return "{whites:" + whites +
                ", blacks:" + blacks +
                ", rate:" + rate +
                '}';
    }
}
